#include "Semaforo.h"
#include <iostream>

Semaforo::Semaforo() {

}

Semaforo::Semaforo(const std::string& nombre, const int id ) {
	key_t clave = ftok( nombre.c_str(),id );
	this->id = semget(clave,1, IPC_CREAT | 0666 );
}

Semaforo::Semaforo(const std::string& nombre, const int id, const int valorInicial) :
		valorInicial(valorInicial), nombre(nombre) {
	key_t clave = ftok(nombre.c_str(), id);
	this->id = semget(clave, 1, 0666 | IPC_CREAT);
	this->inicializar();
}

Semaforo::Semaforo(const Semaforo& otro) :
		id(otro.id), valorInicial(otro.valorInicial) {
	this->inicializar();
}

void Semaforo::operator=(const Semaforo& otro)
{
	valorInicial = otro.valorInicial;
	id = otro.id;
	this->inicializar();
}
Semaforo::~Semaforo() {
}

int Semaforo::inicializar() const {

	union semnum {
		int val;
		struct semid_ds* buf;
		ushort* array;
	};

	semnum init;
	init.val = this->valorInicial;
	int resultado = semctl(this->id, 0, SETVAL, init);
	return resultado;
}

int Semaforo::p() const {

	struct sembuf operacion;

	operacion.sem_num = 0; // numero de semaforo
	operacion.sem_op = -1; // restar 1 al semaforo
	operacion.sem_flg = SEM_UNDO;

	int resultado = semop(this->id, &operacion, 1);
	return resultado;
}

int Semaforo::v() const {

	struct sembuf operacion;

	operacion.sem_num = 0; // numero de semaforo
	operacion.sem_op = 1; // sumar 1 al semaforo
	operacion.sem_flg = SEM_UNDO;

	int resultado = semop(this->id, &operacion, 1);
	return resultado;
}

void Semaforo::eliminar() const {
	semctl(this->id, 0, IPC_RMID, NULL);
}
